package org.csu.onlineedubackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.csu.onlineedubackend.dto.*;
import org.csu.onlineedubackend.entity.*;
import org.csu.onlineedubackend.mapper.*;
import org.csu.onlineedubackend.service.UserService;
import org.csu.onlineedubackend.util.SmsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import javax.annotation.Resource;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.stream.Collectors;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.csu.onlineedubackend.util.HashIdUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private SmsUtil smsUtil;

    @Resource
    private UserMapper userMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private ChapterMapper chapterMapper;

    @Autowired
    private LessonMapper lessonMapper;

    @Autowired
    private CourseCommentMapper courseCommentMapper;

    @Autowired
    private StudentCourseMapper studentCourseMapper;

    @Autowired
    private StudentAnswerMapper studentAnswerMapper;

    @Autowired
    private LessonProgressMapper lessonProgressMapper;

    @Autowired
    private CourseSubscribeMapper courseSubscribeMapper;

    @Override
    public Map<String, Object> login(LoginDTO loginDTO) {
        Map<String, Object> result = new HashMap<>();


        // 验证验证码
        String captchaCode = redisTemplate.opsForValue().get("captcha:" + loginDTO.getCaptchaKey());
        if (captchaCode == null || !captchaCode.equalsIgnoreCase(loginDTO.getCaptchaCode())) {
            throw new RuntimeException("验证码错误或已过期");
        }
        redisTemplate.delete("captcha:" + loginDTO.getCaptchaKey());

        // 查询用户
        User user = getUserByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }


        // 生成会话ID
        String sessionId = UUID.randomUUID().toString();

        // 将用户信息存入Redis，设置24小时过期
        redisTemplate.opsForValue().set("session:" + sessionId, String.valueOf(user.getId()), 24, TimeUnit.HOURS);

        // 构建返回数据
        if (!loginDTO.getPassword().equals(user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        // Sa-Token登录
        StpUtil.login(user.getId());
        String token = StpUtil.getTokenValue();

        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("name", user.getName());
        userInfo.put("role", user.getRole());

        Map<String, Object> tokenInfo = new HashMap<>();
        tokenInfo.put("tokenName", "satoken");
        tokenInfo.put("tokenValue", token);
        tokenInfo.put("expireTime", StpUtil.getTokenTimeout());

        result.put("userInfo", userInfo);
        result.put("saTokenInfo", tokenInfo);

        return result;
    }

    @Override
    public User getUserByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper);
    }

    @Override
    public boolean checkUsernameExists(String username) {
        User user = getUserByUsername(username);
        return user != null;
    }

    @Override
    public boolean checkPhoneExists(String phone) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        User user = getOne(queryWrapper);
        return user != null;
    }

    @Override
    public Map<String, Object> register(RegisterDTO registerDTO) {
        Map<String, Object> result = new HashMap<>();

        // 验证密码长度
        if (registerDTO.getPassword().length() < 6) {
            throw new RuntimeException("密码长度不能少于6位");
        }

        // 验证用户名是否存在
        if (checkUsernameExists(registerDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 验证手机号是否存在
        if (checkPhoneExists(registerDTO.getPhone())) {
            throw new RuntimeException("手机号已被注册");
        }

        // 验证手机号格式
        if (!Pattern.matches("^1[3-9]\\d{9}$", registerDTO.getPhone())) {
            throw new RuntimeException("手机号格式不正确");
        }

        // 验证短信验证码
        if (!smsUtil.verifySmsCode(registerDTO.getPhone(), registerDTO.getSmsCode())) {
            throw new RuntimeException("短信验证码错误或已过期");
        }

        // 验证认证码
        int role = validateAuthCode(registerDTO.getAuthCode());
        if (role == -1) {
            throw new RuntimeException("认证码无效");
        }

        // 创建用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(registerDTO.getPassword()); // 明文密码，不加密
        user.setPhone(registerDTO.getPhone());
        user.setName(registerDTO.getName());
        user.setRole(role);

        // 保存用户
        save(user);

        // 返回结果
        result.put("success", true);
        result.put("userId", user.getId());
        result.put("role", user.getRole());

        return result;
    }

    @Override
    public int validateAuthCode(String authCode) {
        // 验证学生认证码
        if (authCode.startsWith("student") && authCode.length() == 10) {
            try {
                // 提取并验证数字部分
                String numPart = authCode.substring(7);
                int num = Integer.parseInt(numPart);
                if (num >= 100 && num <= 999) {
                    return 1; // 学生角色
                }
            } catch (NumberFormatException e) {
                return -1;
            }
        }

        // 验证教师认证码
        else if (authCode.startsWith("teacher") && authCode.length() == 10) {
            try {
                // 提取并验证数字部分
                String numPart = authCode.substring(7);
                int num = Integer.parseInt(numPart);
                if (num >= 100 && num <= 999) {
                    return 2; // 教师角色
                }
            } catch (NumberFormatException e) {
                return -1;
            }
        }

        // 验证管理员认证码
        else if (authCode.startsWith("admin") && authCode.length() == 8) {
            try {
                // 提取并验证数字部分
                String numPart = authCode.substring(5);
                int num = Integer.parseInt(numPart);
                if (num >= 100 && num <= 999) {
                    return 3; // 管理员角色
                }
            } catch (NumberFormatException e) {
                return -1;
            }
        }

        return -1; // 无效认证码
    }

    @Override
    public void updateFaceRegisteredStatus(Integer userId, boolean status) {
        User user = new User();
        user.setId(userId);
        user.setIsFaceRegistered(status);
        this.updateById(user);
    }

    @Override
    public Map<String, Object> loginById(Integer userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        StpUtil.login(userId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("name", user.getName());
        userInfo.put("role", user.getRole());

        Map<String, Object> result = new HashMap<>();
        result.put("userInfo", userInfo);
        result.put("saTokenInfo", tokenInfo);

        return result;
    }

    @Override
    public Map<String, Object> loginByPhone(String phone, String smsCode) {
        // 1. 验证短信验证码
        if (!smsUtil.verifySmsCode(phone, smsCode)) {
            throw new RuntimeException("短信验证码错误或已过期");
        }
        // 2. 根据手机号查询用户
        User user = getUserByPhone(phone);
        if (user == null) {
            throw new RuntimeException("该手机号未注册");
        }
        // Sa-Token登录
        StpUtil.login(user.getId());
        String token = StpUtil.getTokenValue();

        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("name", user.getName());
        userInfo.put("role", user.getRole());

        Map<String, Object> tokenInfo = new HashMap<>();
        tokenInfo.put("tokenName", "satoken");
        tokenInfo.put("tokenValue", token);
        tokenInfo.put("expireTime", StpUtil.getTokenTimeout());

        Map<String, Object> result = new HashMap<>();
        result.put("userInfo", userInfo);
        result.put("saTokenInfo", tokenInfo);

        return result;
    }

    @Override
    public User getUserByPhone(String phone) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        return getOne(queryWrapper);
    }

    @Override
    public List<User> list() {
        return baseMapper.selectList(null);
    }

    @Override
    public Map<String, Object> phoneLogin(PhoneLoginDTO phoneLoginDTO) {
        // 验证短信验证码
        if (!smsUtil.verifySmsCode(phoneLoginDTO.getPhone(), phoneLoginDTO.getSmsCode())) {
            throw new RuntimeException("短信验证码错误或已过期");
        }

        // 查询用户
        User user = getUserByPhone(phoneLoginDTO.getPhone());
        if (user == null) {
            throw new RuntimeException("该手机号未注册");
        }

        // 使用Sa-Token登录
        StpUtil.login(user.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        // 构建返回数据
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("name", user.getName());
        userInfo.put("role", user.getRole());

        Map<String, Object> result = new HashMap<>();
        result.put("userInfo", userInfo);
        result.put("saTokenInfo", tokenInfo);

        return result;
    }

    @Override
    public Map<String, Object> getStudentStats() {
        Map<String, Object> stats = new HashMap<>();

        // 查询学生总数 (role = 1 表示学生)
        LambdaQueryWrapper<User> totalQuery = new LambdaQueryWrapper<>();
        totalQuery.eq(User::getRole, 1);
        long totalStudents = count(totalQuery);

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 查询上个月的学生数量
        LocalDateTime lastMonth = now.minusMonths(1);
        LocalDateTime lastMonthStart = lastMonth.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime lastMonthEnd = lastMonth.withDayOfMonth(lastMonth.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        LambdaQueryWrapper<User> lastMonthQuery = new LambdaQueryWrapper<>();
        lastMonthQuery.eq(User::getRole, 1)
                     .between(User::getCreatedAt, lastMonthStart, lastMonthEnd);
        long lastMonthStudents = count(lastMonthQuery);

        // 查询上上个月的学生数量
        LocalDateTime twoMonthsAgo = now.minusMonths(2);
        LocalDateTime twoMonthsAgoStart = twoMonthsAgo.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime twoMonthsAgoEnd = twoMonthsAgo.withDayOfMonth(twoMonthsAgo.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        LambdaQueryWrapper<User> twoMonthsAgoQuery = new LambdaQueryWrapper<>();
        twoMonthsAgoQuery.eq(User::getRole, 1)
                        .between(User::getCreatedAt, twoMonthsAgoStart, twoMonthsAgoEnd);
        long twoMonthsAgoStudents = count(twoMonthsAgoQuery);

        // 计算增长率
        double growthRate = 0.0;
        if (twoMonthsAgoStudents > 0) {
            growthRate = ((double) (lastMonthStudents - twoMonthsAgoStudents) / twoMonthsAgoStudents) * 100;
        }

        // 格式化增长率，保留两位小数
        String formattedGrowthRate = String.format("%.2f", growthRate);

        stats.put("totalStudents", totalStudents);
        stats.put("lastMonthStudents", lastMonthStudents);
        stats.put("twoMonthsAgoStudents", twoMonthsAgoStudents);
        stats.put("growthRate", formattedGrowthRate);
        stats.put("growthDirection", growthRate >= 0 ? "up" : "down");

        return stats;
    }

    @Override
    public Map<String, Object> getTeacherStats() {
        Map<String, Object> stats = new HashMap<>();

        // 查询教师总数 (role = 2 表示教师)
        LambdaQueryWrapper<User> totalQuery = new LambdaQueryWrapper<>();
        totalQuery.eq(User::getRole, 2);
        long totalTeacher = count(totalQuery);

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 查询上个月的教师数量
        LocalDateTime lastMonth = now.minusMonths(1);
        LocalDateTime lastMonthStart = lastMonth.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime lastMonthEnd = lastMonth.withDayOfMonth(lastMonth.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        LambdaQueryWrapper<User> lastMonthQuery = new LambdaQueryWrapper<>();
        lastMonthQuery.eq(User::getRole, 2)
                .between(User::getCreatedAt, lastMonthStart, lastMonthEnd);
        long lastMonthTeachers = count(lastMonthQuery);

        // 查询上上个月的教师数量
        LocalDateTime twoMonthsAgo = now.minusMonths(2);
        LocalDateTime twoMonthsAgoStart = twoMonthsAgo.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime twoMonthsAgoEnd = twoMonthsAgo.withDayOfMonth(twoMonthsAgo.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        LambdaQueryWrapper<User> twoMonthsAgoQuery = new LambdaQueryWrapper<>();
        twoMonthsAgoQuery.eq(User::getRole, 2)
                .between(User::getCreatedAt, twoMonthsAgoStart, twoMonthsAgoEnd);
        long twoMonthsAgoTeachers = count(twoMonthsAgoQuery);

        // 计算增长率
        double growthRate = 0.0;
        if (twoMonthsAgoTeachers > 0) {
            growthRate = ((double) (lastMonthTeachers - twoMonthsAgoTeachers) / twoMonthsAgoTeachers) * 100;
        }

        // 格式化增长率，保留两位小数
        String formattedGrowthRate = String.format("%.2f", growthRate);

        stats.put("totalTeachers", totalTeacher);
        stats.put("lastMonthTeachers", lastMonthTeachers);
        stats.put("twoMonthsAgoTeachers", twoMonthsAgoTeachers);
        stats.put("growthRate", formattedGrowthRate);
        stats.put("growthDirection", growthRate >= 0 ? "up" : "down");

        return stats;
    }


    @Override
    public List<Map<String, Object>> getMonthlyRegisteredStudents() {
        List<Map<String, Object>> result = new java.util.ArrayList<>();
        List<Map<String, Object>> dbResult = userMapper.getMonthlyRegisteredStudents();
        if (dbResult != null) {
            result.addAll(dbResult);
        }
        return result;
    }

    @Override
    public PageResponseDTO<StudentListDTO> getStudentPage(int page, int size, String sortField) {
//        Page<User> pageParam = new Page<>(page, size);
//        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(User::getRole, 1); // 学生
//        IPage<User> userPage = this.page(pageParam, wrapper);
//
//// ⚠️ 把 .toList() 改成 new ArrayList<>(...)
//        List<StudentListDTO> dtoList = new ArrayList<>(userPage.getRecords().stream().map(user -> {
//            StudentListDTO dto = new StudentListDTO();
//            dto.setName(user.getName());
//            dto.setStudentId(HashIdUtil.generateHashId(user.getId()));
//            dto.setPhone(user.getPhone());
//            dto.setCreatedAt(user.getCreatedAt());
//            dto.setAvatarUrl(user.getAvatar());
//            dto.setId(user.getId());
//            // 解题数、完成课程数、学习时长
//            int answerCount = studentAnswerMapper.countByStudentId(user.getId());
//            int finishedCourseCount = studentCourseMapper.countFinishedCourses(user.getId());
//            Integer totalLearnMinutes = lessonProgressMapper.sumLearnMinutes(user.getId());
//            dto.setSolveQuestionNum(answerCount);
//            dto.setFinishCourseNum(finishedCourseCount);
//            dto.setStudyTime(totalLearnMinutes != null ? totalLearnMinutes : 0);
//            return dto;
//        }).toList());  // ⚠️ 这里包一层 new ArrayList<>(...)
//
//        // 根据 sortField 排序（降序）
//        if (sortField != null) {
//            switch (sortField) {
//                case "solveQuestionNum" -> dtoList.sort(Comparator.comparing(StudentListDTO::getSolveQuestionNum).reversed());
//                case "finishCourseNum" -> dtoList.sort(Comparator.comparing(StudentListDTO::getFinishCourseNum).reversed());
//                case "studyTime" -> dtoList.sort(Comparator.comparing(StudentListDTO::getStudyTime).reversed());
//                default -> {} // 不排序
//            }
//        }
//
//        // 手动分页（因为 IPage 已经从 DB 分页，但排序改变了顺序，这里要重新分页）
//        int fromIndex = Math.min((page - 1) * size, dtoList.size());
//        int toIndex = Math.min(fromIndex + size, dtoList.size());
//        List<StudentListDTO> pagedList = dtoList.subList(fromIndex, toIndex);
//
//        return new PageResponseDTO<>(pagedList, dtoList.size(), size, page);
        // 查询所有学生
        List<User> users = this.list(new LambdaQueryWrapper<User>().eq(User::getRole, 1));
        List<Integer> studentIds = users.stream().map(User::getId).collect(Collectors.toList());

        // 批量查询统计数据
        List<StudentCountDTO> answerList = studentAnswerMapper.countAnswerByStudentIds();
        List<StudentCountDTO> finishedCourseList = studentCourseMapper.countFinishedCoursesByStudentIds();
        List<StudentCountDTO> learnMinutesList = lessonProgressMapper.sumLearnMinutesByStudentIds();


        // 转成Map便于查找
        Map<Integer, Integer> answerMap = answerList.stream()
                .collect(Collectors.toMap(StudentCountDTO::getStudentId, StudentCountDTO::getCount));
        Map<Integer, Integer> finishedCourseMap = finishedCourseList.stream()
                .collect(Collectors.toMap(StudentCountDTO::getStudentId, StudentCountDTO::getCount));
        Map<Integer, Integer> learnMinutesMap = learnMinutesList.stream()
                .collect(Collectors.toMap(StudentCountDTO::getStudentId, StudentCountDTO::getCount));

        // 构造DTO
        List<StudentListDTO> dtoList = users.stream().map(user -> {
            StudentListDTO dto = new StudentListDTO();
            dto.setId(user.getId());
            dto.setStudentId(HashIdUtil.generateHashId(user.getId()));
            dto.setName(user.getName());
            dto.setPhone(user.getPhone());
            dto.setCreatedAt(user.getCreatedAt());
            dto.setAvatarUrl(user.getAvatar());

            dto.setSolveQuestionNum(answerMap.getOrDefault(user.getId(), 0));
            dto.setFinishCourseNum(finishedCourseMap.getOrDefault(user.getId(), 0));
            dto.setStudyTime(learnMinutesMap.getOrDefault(user.getId(), 0));

            return dto;
        }).collect(Collectors.toList());

        // 排序
        if (sortField != null) {
            switch (sortField) {
                case "solveQuestionNum" -> dtoList.sort(Comparator.comparing(StudentListDTO::getSolveQuestionNum).reversed());
                case "finishCourseNum" -> dtoList.sort(Comparator.comparing(StudentListDTO::getFinishCourseNum).reversed());
                case "studyTime" -> dtoList.sort(Comparator.comparing(StudentListDTO::getStudyTime).reversed());
                default -> {}
            }
        }

        // 分页
        int fromIndex = Math.min((page - 1) * size, dtoList.size());
        int toIndex = Math.min(fromIndex + size, dtoList.size());
        List<StudentListDTO> pagedList = dtoList.subList(fromIndex, toIndex);

        return new PageResponseDTO<>(pagedList, dtoList.size(), size, page);
    }

    @Override
    public List<StudentListDTO> getTopStudents(String sort, int limit){
        // 查询所有学生用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getRole, 1); // 只查学生
        List<User> users = this.list(wrapper);

        // 构造DTO并统计数据
        List<StudentListDTO> dtoList = users.stream().map(user -> {
            StudentListDTO dto = new StudentListDTO();
            dto.setName(user.getName());
            dto.setStudentId(HashIdUtil.generateHashId(user.getId()));
            dto.setPhone(user.getPhone());
            dto.setCreatedAt(user.getCreatedAt());
            dto.setAvatarUrl(user.getAvatar());
            dto.setId(user.getId());

            // 动态统计数据
            int answerCount = studentAnswerMapper.countByStudentId(user.getId());
            int finishedCourseCount = studentCourseMapper.countFinishedCourses(user.getId());
            Integer totalLearnMinutes = lessonProgressMapper.sumLearnMinutes(user.getId());

            dto.setSolveQuestionNum(answerCount);
            dto.setFinishCourseNum(finishedCourseCount);
            dto.setStudyTime(totalLearnMinutes != null ? totalLearnMinutes : 0);
            return dto;
        }).toList();

        // 按排序字段降序排序
        Comparator<StudentListDTO> comparator = switch (sort) {
            case "solveQuestionNum" -> Comparator.comparing(StudentListDTO::getSolveQuestionNum).reversed();
            case "finishCourseNum" -> Comparator.comparing(StudentListDTO::getFinishCourseNum).reversed();
            case "studyTime" -> Comparator.comparing(StudentListDTO::getStudyTime).reversed();
            default -> Comparator.comparing(StudentListDTO::getStudyTime).reversed(); // 默认按学习时长
        };

        return dtoList.stream()
                .sorted(comparator)
                .limit(limit)
                .toList();
    }

    @Override
    public PageResponseDTO<TeacherListDTO> getTeacherPage(int page, int size) {
        Page<User> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getRole, 2); // 教师
        IPage<User> userPage = this.page(pageParam, wrapper);
        List<TeacherListDTO> dtoList = userPage.getRecords().stream().map(user -> {
            TeacherListDTO dto = new TeacherListDTO();
            dto.setName(user.getName());
            dto.setTeacherId(org.csu.onlineedubackend.util.HashIdUtil.generateHashId(user.getId()));
            dto.setAvatarUrl(user.getAvatar());
            dto.setCreatedAt(user.getCreatedAt());
            // 教师收入
            dto.setTotalIncome(courseMapper.selectTotalIncomeByTeacherId(user.getId()));
            // 教师开课数
            dto.setCourseCount(courseMapper.selectByTeacherId(user.getId()).size());
            dto.setId(user.getId());
            return dto;
        }).toList();
        return new PageResponseDTO<>(dtoList, userPage.getTotal(), userPage.getSize(), userPage.getCurrent());
    }

    @Override
    public Map<Integer, String> getUserNamesByIds(Set<Integer> userIds) {
        if (userIds == null || userIds.isEmpty()) return Collections.emptyMap();
        List<User> users = userMapper.selectNamesByIds(new ArrayList<>(userIds));
        return users.stream().collect(Collectors.toMap(User::getId, User::getName));
    }

    @Override
    public TeacherDetailDTO getTeacherDetail(Integer teacherId) {
        // 获取教师基本信息
        User teacher = userMapper.selectById(teacherId);
        if (teacher == null) {
            return null;
        }

        // 构建TeacherDetailDTO
        TeacherDetailDTO teacherDetailDTO = new TeacherDetailDTO();
        teacherDetailDTO.setId(teacher.getId());
        teacherDetailDTO.setName(teacher.getName());
        teacherDetailDTO.setTeacherId(HashIdUtil.generateHashId(teacher.getId()));
        teacherDetailDTO.setAvatarUrl(teacher.getAvatar());
        teacherDetailDTO.setPhone(teacher.getPhone());
        teacherDetailDTO.setCreatedAt(teacher.getCreatedAt());

        // 获取该教师的所有课程
        LambdaQueryWrapper<Course> courseWrapper = new LambdaQueryWrapper<>();
        courseWrapper.eq(Course::getTeacherId, teacherId);
        List<Course> courses = courseMapper.selectList(courseWrapper);

        // 获取老师所有课程id
        List<Integer> courseIds = courses.stream().map(Course::getId).collect(Collectors.toList());

        // 设置课程总数
        teacherDetailDTO.setCourseCount(courses.size());

        // 计算总收入（所有课程价格之和）
        BigDecimal totalIncome = BigDecimal.ZERO;
        List<CoursesOfTeacherDTO> coursesDTOs = new ArrayList<>();

        // 获取评论数、学生数、平均分
        if (!courseIds.isEmpty()) {
            Map<String, Object> commentStats = courseCommentMapper.getCommentStatsByCourseIds(courseIds);
            teacherDetailDTO.setCommentCount(((Long)commentStats.get("commentCount")).intValue());
            BigDecimal avgStars = (BigDecimal) commentStats.get("avgStars");
            teacherDetailDTO.setAvgStart(avgStars.doubleValue());

            // 2. 查询所有订阅这些课程的记录
            List<CourseSubscribe> subscribes = courseSubscribeMapper.selectList(
                    new QueryWrapper<CourseSubscribe>().in("course_id", courseIds)
            );

            // 3. 提取学生 ID 并去重计数
            Set<Integer> studentIds = subscribes.stream()
                    .map(CourseSubscribe::getStudentId)
                    .collect(Collectors.toSet());
            teacherDetailDTO.setStudentCount(studentIds.size());
        } else {
            teacherDetailDTO.setCommentCount(0);
            teacherDetailDTO.setAvgStart(0);
            teacherDetailDTO.setStudentCount(0);
        }
        
        for (Course course : courses) {
            // 累加课程价格到总收入
            if (course.getPrice() != null) {
                totalIncome = totalIncome.add(course.getPrice());
            }

            // 构建CoursesOfTeacherDTO
            CoursesOfTeacherDTO courseDTO = new CoursesOfTeacherDTO();
            courseDTO.setId(course.getId());
            courseDTO.setCourseId(HashIdUtil.generateHashId(teacher.getId()));
            courseDTO.setTitle(course.getTitle());
            courseDTO.setCategory(course.getCategory());
            courseDTO.setLevel(course.getLevel());
            courseDTO.setCoverUrl(course.getCoverUrl());
            courseDTO.setIntroMd(course.getIntroMd());
            courseDTO.setPrice(course.getPrice());
            courseDTO.setPreviewPercent(course.getPreviewPercent());
            courseDTO.setStatus(course.getStatus());
            courseDTO.setCreatedAt(course.getCreatedAt());
            courseDTO.setUpdatedAt(course.getUpdatedAt());
            courseDTO.setSubscriberCount(course.getSubscriberCount() != null ? course.getSubscriberCount() : 0);
//
//            // 获取课程章节信息
            QueryWrapper<Chapter> chapterWrapper = new QueryWrapper<>();
            chapterWrapper.eq("course_id", course.getId());
            chapterWrapper.orderByAsc("sort_order");
            List<Chapter> chapters = chapterMapper.selectList(chapterWrapper);
//
//            List<ChapterDTO> chapterDTOs = new ArrayList<>();
            int totalDuration = 0;
//
            for (Chapter chapter : chapters) {
//                ChapterDTO chapterDTO = new ChapterDTO();
//                chapterDTO.setId(chapter.getId().longValue());
//                chapterDTO.setTitle(chapter.getTitle());
//                chapterDTO.setSortOrder(chapter.getSortOrder());
//                chapterDTO.setCourseId(chapter.getCourseId().longValue());
//
//                // 获取该章节下的所有课程
                QueryWrapper<Lesson> lessonWrapper = new QueryWrapper<>();
                lessonWrapper.eq("chapter_id", chapter.getId());
                lessonWrapper.orderByAsc("sort_order");
                List<Lesson> lessons = lessonMapper.selectList(lessonWrapper);
//                chapterDTO.setLessons(lessons);
//
//                // 计算章节总时长
                int chapterDuration = 0;
                for (Lesson lesson : lessons) {
                    if (lesson.getDuration() != null) {
                        chapterDuration += lesson.getDuration();
                    }
                }
//                chapterDTO.setDuration(chapterDuration);
                totalDuration += chapterDuration;
//
//                chapterDTOs.add(chapterDTO);
            }
//
//            courseDTO.setChapters(chapterDTOs);
            courseDTO.setTotalDuration(totalDuration);
            coursesDTOs.add(courseDTO);
        }

        teacherDetailDTO.setTotalIncome(totalIncome);
        teacherDetailDTO.setCourses(coursesDTOs);

        return teacherDetailDTO;
    }

    @Override
    public StudentDetailDTO getStudentDetail(Integer studentId) {
        // 获取学生基本信息
        User student = userMapper.selectById(studentId);
        if (student == null) {
            return null;
        }

        // 构建StudentDetailDTO
        StudentDetailDTO studentDetailDTO = new StudentDetailDTO();
        Integer id = student.getId();
        studentDetailDTO.setId(id);
        studentDetailDTO.setName(student.getName());
        studentDetailDTO.setStudentId(HashIdUtil.generateHashId(id));
        studentDetailDTO.setAvatarUrl(student.getAvatar());
        studentDetailDTO.setPhone(student.getPhone());
        studentDetailDTO.setCreatedAt(student.getCreatedAt());

        // 获取该学生的回答问题数
        int answerCount = studentAnswerMapper.countByStudentId(studentId);                                                                  
        // 获得该学生完成的课堂数
        int finishedCourseCount = studentCourseMapper.countFinishedCourses(studentId);
        // 统计所有已购课程下所有lesson_progress的 progress*lesson.duration 之和
        Integer totalLearnMinutes = lessonProgressMapper.sumLearnMinutes(studentId);

        // 查询所有已订阅课程
        List<Map<String, Object>> studentCourses = courseSubscribeMapper.getSubscribedCoursesByUserId(Long.valueOf(id));
//        System.out.println("-------------");
//        System.out.println(studentCourses);
        List<CoursesOfStudentDTO> courseDTOList = new ArrayList<>();
        for (Map<String, Object> sc : studentCourses) {
            Integer courseId = (Integer) sc.get("id");
            Course course = courseMapper.selectById(courseId);
            if (course == null) continue;
            CoursesOfStudentDTO dto = new CoursesOfStudentDTO();
            dto.setId(course.getId());
            dto.setCourseId(HashIdUtil.generateHashId(course.getId()));
            dto.setTitle(course.getTitle());
            dto.setCategory(course.getCategory());
            dto.setLevel(course.getLevel());
            dto.setCoverUrl(course.getCoverUrl());
            // 动态计算进度
            int courseProgress = this.getStudentTotalProgress(course.getId(), studentId);
            dto.setCourseProgress(courseProgress);

            courseDTOList.add(dto);
        }
        studentDetailDTO.setCourses(courseDTOList);
        studentDetailDTO.setSolveQuestionNum(answerCount);
        studentDetailDTO.setFinishCourseNum(finishedCourseCount);
        studentDetailDTO.setStudyTime(totalLearnMinutes);
        return studentDetailDTO;
    }

    public int getStudentTotalProgress(Integer courseId, Integer studentId) {
        List<Lesson> lessons = lessonMapper.getLessonsByCourseId(courseId);
        if (lessons.isEmpty()) return 0;

        List<Integer> lessonIds = lessons.stream().map(Lesson::getId).collect(Collectors.toList());
        List<LessonProgress> progresses = lessonProgressMapper.selectByStudentIdAndLessonIds(studentId, lessonIds);

        Map<Integer, Float> progressMap = new HashMap<>();
        for (LessonProgress lp : progresses) {
            progressMap.put(lp.getLessonId(), lp.getProgress());
        }

        double avg = lessons.stream()
                .mapToDouble(lesson -> progressMap.getOrDefault(lesson.getId(), 0.0f))
                .average()
                .orElse(0.0);

        return (int) avg;
    }



}

